package g04;
/**
* <p>Title: Client Class</p>
* <p>Description: CS 235 Assignment #4</p>
* @email Ryan.Novak@my.uwrf.edu
* @date December 14th 2011
* @team Ryan Novak, Dan Prayfrock, Curtis Paulson, Meizer Yang
*/

import java.awt.Color;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

import javax.swing.GroupLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.Timer;

public class Client extends JFrame implements ActionListener {

	private static final long serialVersionUID = 1L;
	boolean server_player = true;
	private JButton a1 = new JButton();
	private JButton b1 = new JButton();
	private JButton c1 = new JButton();
	private JButton a2 = new JButton();
	private JButton b2 = new JButton();
	private JButton c2 = new JButton();
	private JButton a3 = new JButton();
	private JButton b3 = new JButton();
	private JButton c3 = new JButton();
	private JButton sendButton = new JButton();
	private String response = "";
	private String sendString = "";
	private Timer timer;
	/*
	 * Network connections
	 */
	private int port = 5555;
	private Socket connection;
	private String server_address = "172.16.1.12";
	/*
	 * Streams for network connections
	 */
	BufferedReader instream;
	PrintWriter outstream;

	/**
	 * Constructor for the Client.  It initializes the GUI.
	 */
	public Client() {
		a1.addActionListener(this);
		a2.addActionListener(this);
		a3.addActionListener(this);
		b1.addActionListener(this);
		b2.addActionListener(this);
		b3.addActionListener(this);
		c1.addActionListener(this);
		c2.addActionListener(this);
		c3.addActionListener(this);
		sendButton.setText("Wait");
		sendButton.setEnabled(false);
		sendButton.addActionListener(this);
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		Container mainPanel = this.getContentPane();
		mainPanel.setBackground(Color.black);
		GroupLayout layout = new GroupLayout(mainPanel);
		mainPanel.setLayout(layout);
		layout.setAutoCreateGaps(true);
		layout.setHorizontalGroup(layout
				.createSequentialGroup()
				.addGroup(
						layout.createParallelGroup(
								GroupLayout.Alignment.LEADING)
								.addComponent(a1, 100, 100, 100)
								.addComponent(a2, 100, 100, 100)
								.addComponent(a3, 100, 100, 100))
				.addGroup(
						layout.createParallelGroup(
								GroupLayout.Alignment.LEADING)
								.addComponent(b1, 100, 100, 100)
								.addComponent(b2, 100, 100, 100)
								.addComponent(b3, 100, 100, 100)
								.addComponent(sendButton, 100, 100, 100))
				.addGroup(
						layout.createParallelGroup(
								GroupLayout.Alignment.LEADING)
								.addComponent(c1, 100, 100, 100)
								.addComponent(c2, 100, 100, 100)
								.addComponent(c3, 100, 100, 100)));
		layout.setVerticalGroup(layout
				.createSequentialGroup()
				.addGroup(
						layout.createParallelGroup(
								GroupLayout.Alignment.BASELINE)
								.addComponent(a1, 100, 100, 100)
								.addComponent(b1, 100, 100, 100)
								.addComponent(c1, 100, 100, 100))
				.addGroup(
						layout.createParallelGroup(
								GroupLayout.Alignment.BASELINE)
								.addComponent(a2, 100, 100, 100)
								.addComponent(b2, 100, 100, 100)
								.addComponent(c2, 100, 100, 100))
				.addGroup(
						layout.createParallelGroup(
								GroupLayout.Alignment.BASELINE)
								.addComponent(a3, 100, 100, 100)
								.addComponent(b3, 100, 100, 100)
								.addComponent(c3, 100, 100, 100))
				.addGroup(
						layout.createParallelGroup(
								GroupLayout.Alignment.BASELINE).addComponent(
								sendButton, 30, 30, 30)));
		pack();
		setResizable(false);
		setVisible(true);

		timer = new Timer(1000, this);
		timer.start();

		/*
		 * Set up network connections
		 */
		try {

			connection = new Socket(server_address, port);
			outstream = new PrintWriter(connection.getOutputStream(), true);

			System.out.println(" Connected to " + connection.getInetAddress()
					+ ":" + connection.getPort() + " using local port "
					+ connection.getLocalPort());
			InputStreamReader ins = new InputStreamReader(
					connection.getInputStream());
			instream = new BufferedReader(ins);
		} catch (IOException ioe) {
			System.out.println("Not able to connect on port " + port);
		}
	}

	/**
	 * This method handles button clicks and the timer.
	 * @require: evt.getSource() == timer || evt.getSource() == JButton
	 */	
	public void actionPerformed(ActionEvent evt) {
		if (evt.getSource().equals(timer)) {
			try {
				if (instream != null && instream.ready())
					response = instream.readLine();
				else {
					response = "";
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
			if (response.equals("a1")) {
				a1.setText("o");
				a1.setEnabled(false);
				sendButton.setText("Send");
				sendButton.setEnabled(true);
				winCond();
			} else if (response.equals("a2")) {
				a2.setText("o");
				a2.setEnabled(false);
				sendButton.setText("Send");
				sendButton.setEnabled(true);
				winCond();
			} else if (response.equals("a3")) {
				a3.setText("o");
				a3.setEnabled(false);
				sendButton.setText("Send");
				sendButton.setEnabled(true);
				winCond();
			} else if (response.equals("b1")) {
				b1.setText("o");
				b1.setEnabled(false);
				sendButton.setText("Send");
				sendButton.setEnabled(true);
				winCond();
			} else if (response.equals("b2")) {
				b2.setText("o");
				b2.setEnabled(false);
				sendButton.setText("Send");
				sendButton.setEnabled(true);
				winCond();
			} else if (response.equals("b3")) {
				b3.setText("o");
				b3.setEnabled(false);
				sendButton.setText("Send");
				sendButton.setEnabled(true);
				winCond();
			} else if (response.equals("c1")) {
				c1.setText("o");
				c1.setEnabled(false);
				sendButton.setText("Send");
				sendButton.setEnabled(true);
				winCond();
			} else if (response.equals("c2")) {
				c2.setText("o");
				c2.setEnabled(false);
				sendButton.setText("Send");
				sendButton.setEnabled(true);
				winCond();
			} else if (response.equals("c3")) {
				c3.setText("o");
				c3.setEnabled(false);
				sendButton.setText("Send");
				sendButton.setEnabled(true);
				winCond();
			}
			if(!(sendButton.isEnabled())) winCond();
		}
		if (evt.getSource() instanceof JButton) {
			if (evt.getSource() == sendButton) {
				if (!(sendString.equals(""))) {
					if (outstream != null) {
						outstream.println(sendString);
						sendButton.setText("Wait");
						sendButton.setEnabled(false);
					}
				}
			}
			if (evt.getSource() == a1) {
				a1.setText("x");
				a1.setEnabled(false);
				sendString = "a1";
			} else if (evt.getSource() == a2) {
				a2.setText("x");
				a2.setEnabled(false);
				sendString = "a2";
			} else if (evt.getSource() == a3) {
				a3.setText("x");
				a3.setEnabled(false);
				sendString = "a3";
			} else if (evt.getSource() == b1) {
				b1.setText("x");
				b1.setEnabled(false);
				sendString = "b1";
			} else if (evt.getSource() == b2) {
				b2.setText("x");
				b2.setEnabled(false);
				sendString = "b2";
			} else if (evt.getSource() == b3) {
				b3.setText("x");
				b3.setEnabled(false);
				sendString = "b3";
			} else if (evt.getSource() == c1) {
				c1.setText("x");
				c1.setEnabled(false);
				sendString = "c1";
			} else if (evt.getSource() == c2) {
				c2.setText("x");
				c2.setEnabled(false);
				sendString = "c2";
			} else if (evt.getSource() == c3) {
				c3.setText("x");
				c3.setEnabled(false);
				sendString = "c3";
			}
		}
	}

	/**
	 * This method tests to see if the win conditions have been met.
	 * If they have been met, a winner is declared.
	 */
	public void winCond() {
		if ((a1.getText().equals("x") && a2.getText().equals("x") && a3
				.getText().equals("x"))
				|| (a1.getText().equals("x") && b1.getText().equals("x") && c1
						.getText().equals("x"))
				|| (a1.getText().equals("x") && b2.getText().equals("x") && c3
						.getText().equals("x"))
				|| (b1.getText().equals("x") && b2.getText().equals("x") && b3
						.getText().equals("x"))
				|| (c1.getText().equals("x") && c2.getText().equals("x") && c3
						.getText().equals("x"))
				|| (c1.getText().equals("x") && b2.getText().equals("x") && a3
						.getText().equals("x"))
				|| (a2.getText().equals("x") && b2.getText().equals("x") && c2
						.getText().equals("x"))
				|| (a3.getText().equals("x") && b3.getText().equals("x") && c3
						.getText().equals("x"))) {
			JOptionPane.showMessageDialog(this, "X wins!");
			newGame();
		}
		if ((a1.getText().equals("o") && a2.getText().equals("o") && a3
				.getText().equals("o"))
				|| (a1.getText().equals("o") && b1.getText().equals("o") && c1
						.getText().equals("o"))
				|| (a1.getText().equals("o") && b2.getText().equals("o") && c3
						.getText().equals("o"))
				|| (b1.getText().equals("o") && b2.getText().equals("o") && b3
						.getText().equals("o"))
				|| (c1.getText().equals("o") && c2.getText().equals("o") && c3
						.getText().equals("o"))
				|| (c1.getText().equals("o") && b2.getText().equals("o") && a3
						.getText().equals("o"))
				|| (a2.getText().equals("o") && b2.getText().equals("o") && c2
						.getText().equals("o"))
				|| (a3.getText().equals("o") && b3.getText().equals("o") && c3
						.getText().equals("o"))) {
			JOptionPane.showMessageDialog(this, "O wins!");
			newGame();
		}
		if (!(a1.isEnabled() || a2.isEnabled() || a3.isEnabled()
				|| b1.isEnabled() || b2.isEnabled() || b3.isEnabled()
				|| c1.isEnabled() || c2.isEnabled() || c3.isEnabled())) {
			JOptionPane.showMessageDialog(this, "Draw...");
			newGame();
		}
	}

	/**
	 * This method makes a new game after the 1st one is completed.
	 * @require:a1.getText().equals("")
	 * 			a2.getText().equals("")
	 * 			a3.getText().equals("")
	 * 			b1.getText().equals("")
	 * 			b2.getText().equals("")
	 * 			b3.getText().equals("")
	 * 			c1.getText().equals("")
	 * 			c2.getText().equals("")
	 * 			c3.getText().equals("")
	 * 			a1.isEnabled() == true
	 * 			a2.isEnabled() == true
	 * 			a3.isEnabled() == true
	 * 			b1.isEnabled() == true
	 * 			b2.isEnabled() == true
	 * 			b3.isEnabled() == true
	 * 			c1.isEnabled() == true
	 * 			c2.isEnabled() == true
	 * 			c3.isEnabled() == true
	 */
	public void newGame() {
		a1.setText("");
		a2.setText("");
		a3.setText("");
		b1.setText("");
		b2.setText("");
		b3.setText("");
		c1.setText("");
		c2.setText("");
		c3.setText("");
		a1.setEnabled(true);
		a2.setEnabled(true);
		a3.setEnabled(true);
		b1.setEnabled(true);
		b2.setEnabled(true);
		b3.setEnabled(true);
		c1.setEnabled(true);
		c2.setEnabled(true);
		c3.setEnabled(true);
	}

	/**
	 * This is the main method.  It calls the constructor for the Client Class.
	 * @param args
	 */
	public static void main(String[] args) {
		new Client();
	}

}